package com.bkgy.modularbx.coil_track_stats.util;

import cn.hutool.core.map.MapUtil;
import com.bkgy.modularbx.coil_track_stats.dto.DefectReasonStatDTO;
import com.bkgy.modularbx.coil_track_stats.dto.StatDataDTO;
import com.bkgy.modularbx.coil_track_stats.dto.SteelGradeInfoDTO;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 统计概括文本构建工具类
 */
public class StatSummaryBuilder {
    
    /**
     * 构建统计信息概括文本
     */
    public static String buildStatSummary(String startDate, String endDate, 
                                         Map<String, List<DefectReasonStatDTO>> groupedByReason, 
                                         Integer dateType, BigDecimal countDifference, BigDecimal totalAddedCosts) {
        StringBuilder summary = new StringBuilder();
        
        // 格式化日期
        String startDateFormatted;
        String endDateFormatted;
        
        if (dateType != null && dateType == 2) {
            // 按月统计：格式化为年月
            startDateFormatted = formatMonthToChinese(startDate);
            endDateFormatted = formatMonthToChinese(endDate);
        } else {
            // 按日统计：格式化为月日
            startDateFormatted = DateFormatter.formatToChineseDate(startDate);
            endDateFormatted = DateFormatter.formatToChineseDate(endDate);
        }
        
        // 头部信息
        summary.append(startDateFormatted).append("~").append(endDateFormatted).append("统计信息如下，\n");
        summary.append("卷重不符损失的重量约为");
        
        // 获取总损失重量（直接使用totalAllLossWeight字段）
        BigDecimal totalLoss = BigDecimal.ZERO;
        if (groupedByReason != null && !groupedByReason.isEmpty()) {
            // 从任意一条记录中获取totalAllLossWeight
            List<DefectReasonStatDTO> firstReasonStats = groupedByReason.values().iterator().next();
            if (firstReasonStats != null && !firstReasonStats.isEmpty()) {
                BigDecimal totalAllLossWeight = firstReasonStats.get(0).getTotalAllLossWeight();
                if (totalAllLossWeight != null) {
                    totalLoss = totalAllLossWeight;
                }
            }
        }
        summary.append(totalLoss.setScale(2, BigDecimal.ROUND_HALF_UP)).append("吨，卷重不符的原因有以下\n");
        
        // 定义预定义的缺陷原因映射
        Map<String, String> reasonDescriptions = MapUtil.builder(new LinkedHashMap<String, String>())
                .put("原料重量不符", "原料重量不满足导致卷重不符")
                .put("质量缺陷原因", "质量缺陷原因导致卷重不符")
                .put("成材率问题", "成材率未达标导致卷重不符")
                .build();

        // 构建每个缺陷原因的描述
        int validReasonCount = 0;
        for (Map.Entry<String, String> entry : reasonDescriptions.entrySet()) {
            String reason = entry.getKey();
            String description = entry.getValue();
            
            List<DefectReasonStatDTO> reasonStats = groupedByReason.get(reason);
            if (reasonStats != null && !reasonStats.isEmpty()) {
                validReasonCount++;

                summary.append(validReasonCount).append(".").append(description).append("，");
                
                // 添加钢种信息
                if (reasonStats.size() > 0) {
                    summary.append("以下牌号：");
                    List<String> steelGrades = reasonStats.stream()
                            .limit(3)
                            .map(stat -> stat.getSteelGrade() + "（" + stat.getTotalLossWeight().setScale(2, BigDecimal.ROUND_HALF_UP) + "吨）")
                            .collect(Collectors.toList());
                    summary.append(String.join("、", steelGrades));
                    summary.append("；\n");
                } else {
                    summary.append("；\n");
                }
            }
        }
        
        // 添加分卷数统计信息
        if (countDifference != null && totalAddedCosts != null && countDifference.compareTo(BigDecimal.ZERO) > 0) {
            validReasonCount++;
            summary.append(validReasonCount).append(".分卷数超过建议值").append(countDifference)
                   .append("卷，增加包装费用约").append(totalAddedCosts.setScale(2, BigDecimal.ROUND_HALF_UP))
                   .append("元；\n");
        }
        
        // 如果没有查询到任何缺陷原因，返回默认信息
        if (validReasonCount == 0) {
            return startDateFormatted + "~" + endDateFormatted + "统计信息如下：，\n" +
                   "卷重不符损失的重量约为" + totalLoss.setScale(2, BigDecimal.ROUND_HALF_UP) + "吨，\n" +
                   "未发现具体的缺陷原因统计信息。";
        }
        
        return summary.toString();
    }
    
    /**
     * 构建新的统计信息文本格式
     * 
     * @param totalLoss 总损失重量
     * @param reasonStatsMap 各缺陷原因的统计数据
     * @param countDifference 分卷数超过建议值
     * @param totalAddedCosts 增加包装费用
     * @return 格式化后的统计文本
     */
    public static String buildNewStatSummary(BigDecimal totalLoss, 
                                            Map<String, StatDataDTO> reasonStatsMap,
                                            BigDecimal countDifference, 
                                            BigDecimal totalAddedCosts) {
        StringBuilder summary = new StringBuilder();
        
        // 头部信息
        summary.append("卷重不符总计损失").append(totalLoss.setScale(2, BigDecimal.ROUND_HALF_UP)).append("吨： \n ");
        
        // 定义预定义的缺陷原因映射
        Map<String, String> reasonDescriptions = MapUtil.builder(new LinkedHashMap<String, String>())
                .put("原料重量不符", "原料重量不匹配导致")
                .put("质量缺陷原因", "质量缺陷切除")
                .put("成材率问题", "成材率波动导致")
                .build();
        
        int index = 1;
        // 构建每个缺陷原因的描述
        for (Map.Entry<String, String> entry : reasonDescriptions.entrySet()) {
            String reason = entry.getKey();
            String description = entry.getValue();
            
            StatDataDTO statData = reasonStatsMap.get(reason);
            if (statData != null) {
                summary.append(index).append("、").append(description)
                       .append(statData.getTotalLoss().setScale(2, BigDecimal.ROUND_HALF_UP))
                       .append("吨、占比")
                       .append(statData.getPercentage())
                       .append("%，");
                
                // 添加钢种信息
                List<SteelGradeInfoDTO> steelGrades = statData.getTopSteelGrades();
                if (steelGrades != null && !steelGrades.isEmpty()) {
                    List<String> steelGradeTexts = steelGrades.stream()
                            .map(gradeInfo -> {
                                String steelGradeText = gradeInfo.getSteelGrade() + "（" + 
                                        gradeInfo.getLossWeight().setScale(2, BigDecimal.ROUND_HALF_UP) + "吨";
                                
                                // 为"原料重量不符"添加"订货卷重范围"描述
                                /*if ("原料重量不符".equals(reason)) {
                                    steelGradeText += "，订货卷重范围XX-XX吨";
                                }*/
                                steelGradeText += "）";
                                return steelGradeText;
                            })
                            .collect(Collectors.toList());
                    summary.append(String.join("、", steelGradeTexts));
                }
                summary.append("。 \n ");
                index++;
            }
        }
        
        // 添加分卷数统计信息
        if (countDifference != null && totalAddedCosts != null && countDifference.compareTo(BigDecimal.ZERO) > 0) {
            summary.append(index).append("、分卷数超过建议值").append(countDifference)
                   .append("卷，增加包装费用约").append(totalAddedCosts.setScale(2, BigDecimal.ROUND_HALF_UP))
                   .append("元。");
        }
        
        return summary.toString();
    }
    
    /**
     * 构建新的统计信息文本格式
     * 
     * @param defectStats 缺陷统计数据列表
     * @param countDifference 分卷数超过建议值
     * @param totalAddedCosts 增加包装费用
     * @return 格式化后的统计文本
     */
    public static String buildNewStatSummary(List<DefectReasonStatDTO> defectStats, 
                                     BigDecimal countDifference, 
                                     BigDecimal totalAddedCosts) {
        // 获取总生产量（从第一条记录中获取）
        BigDecimal totalProduction = BigDecimal.ZERO;
        if (defectStats != null && !defectStats.isEmpty()) {
            totalProduction = defectStats.get(0).getTotalAllWeight();
            if (totalProduction == null) {
                totalProduction = BigDecimal.ZERO;
            }
        }
        
        // 获取总损失重量（从第一条记录中获取）
        BigDecimal totalLoss = BigDecimal.ZERO;
        if (defectStats != null && !defectStats.isEmpty()) {
            totalLoss = defectStats.get(0).getTotalAllLossWeight();
            if (totalLoss == null) {
                totalLoss = BigDecimal.ZERO;
            }
        }
        
        // 计算各缺陷原因的统计数据
        Map<String, StatDataDTO> reasonStatsMap = calculateReasonStats(defectStats, totalProduction);
        
        // 使用buildNewStatSummary构建文本
        return buildNewStatSummary(totalLoss, reasonStatsMap, countDifference, totalAddedCosts);
    }
    
    /**
     * 计算各缺陷原因的统计数据
     * 
     * @param defectStats 缺陷统计数据列表
     * @param totalProduction 总生产量
     * @return 各缺陷原因的统计数据映射
     */
    public static Map<String, StatDataDTO> calculateReasonStats(List<DefectReasonStatDTO> defectStats, BigDecimal totalProduction) {
        Map<String, StatDataDTO> result = new HashMap<>();
        
        // 根据缺陷原因分组
        Map<String, List<DefectReasonStatDTO>> groupedByReason = defectStats.stream()
                .filter(stat -> stat.getDefectReason() != null && !stat.getDefectReason().isEmpty())
                .collect(Collectors.groupingBy(DefectReasonStatDTO::getDefectReason));
        
        // 处理每个缺陷原因
        for (Map.Entry<String, List<DefectReasonStatDTO>> entry : groupedByReason.entrySet()) {
            String reason = entry.getKey();
            List<DefectReasonStatDTO> stats = entry.getValue();
            
            // 根据原因类型获取对应的总损失重量
            BigDecimal reasonTotalLoss = BigDecimal.ZERO;
            if (!stats.isEmpty()) {
                DefectReasonStatDTO firstStat = stats.get(0);
                
                // 根据缺陷原因类型选择对应的总损失字段
                if ("原料重量不符".equals(reason)) {
                    reasonTotalLoss = firstStat.getWeightTotalLoss() != null ? 
                            firstStat.getWeightTotalLoss() : BigDecimal.ZERO;
                } else if ("质量缺陷原因".equals(reason)) {
                    reasonTotalLoss = firstStat.getQualityTotalLoss() != null ? 
                            firstStat.getQualityTotalLoss() : BigDecimal.ZERO;
                } else if ("成材率原因".equals(reason)) {
                    reasonTotalLoss = firstStat.getYieldTotalLoss() != null ? 
                            firstStat.getYieldTotalLoss() : BigDecimal.ZERO;
                }
            }
            
            // 计算占比
            BigDecimal percentage = BigDecimal.ZERO;
            if (totalProduction.compareTo(BigDecimal.ZERO) > 0) {
                percentage = reasonTotalLoss.divide(totalProduction, 4, BigDecimal.ROUND_HALF_UP)
                        .multiply(new BigDecimal(100))
                        .setScale(2, BigDecimal.ROUND_HALF_UP);
            }
            
            // 获取前三个钢种
            List<SteelGradeInfoDTO> topSteelGrades = stats.stream()
                    .limit(3)
                    .map(stat -> new SteelGradeInfoDTO(stat.getSteelGrade(), stat.getTotalLossWeight()))
                    .collect(Collectors.toList());
            
            // 创建统计数据对象
            StatDataDTO statData = new StatDataDTO(reason, reasonTotalLoss, percentage, topSteelGrades);
            result.put(reason, statData);
        }
        
        return result;
    }
    
    /**
     * 格式化月份为中文格式（如：10月）
     * @param monthString 月份字符串，格式 YYYY-MM
     * @return 格式化后的中文月份字符串
     */
    private static String formatMonthToChinese(String monthString) {
        String[] parts = monthString.split("-");
        if (parts.length == 2) {
            int month = Integer.parseInt(parts[1]);
            return month + "月";
        }
        return monthString;
    }
}